/**
 * @file ds.h
 * @brief Data sets
 * @note Copyright (C) 2011 Richard Cochran <richardcochran@gmail.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */
#ifndef HAVE_DS_H
#define HAVE_DS_H

#include "ddt.h"
#include "fault.h"
#include "filter.h"

/* clock data sets */

#define DDS_TWO_STEP_FLAG (1<<0)
#define DDS_SLAVE_ONLY    (1<<1)

struct defaultDS {
	UInteger8            flags;				// reserved（6）| slaveOnly（1） | twoStepFlag（1）
	UInteger8            reserved1;
	UInteger16           numberPorts;		// 表示当前PTP有多少个port端口
	UInteger8            priority1;			// 用于计算最佳 master 时钟，值越低优先级越高
	struct ClockQuality  clockQuality;		// 时钟质量对象
	UInteger8            priority2;			// 用于计算最佳 master 时钟，值越低优先级越高
	struct ClockIdentity clockIdentity;		// 时钟的唯一标识
	UInteger8            domainNumber;		
	UInteger8            reserved2;
} PACKED;

#define OUI_LEN 3
struct clock_description {
	struct static_ptp_text productDescription;
	struct static_ptp_text revisionData;
	struct static_ptp_text userDescription;
	Octet manufacturerIdentity[OUI_LEN];
};

struct default_ds {
	struct defaultDS dds;
	int free_running;			// 是否会自主运行（master状态下）
	int freq_est_interval; 		/*log seconds*/
	int grand_master_capable; 	/*802.1AS only*/
	int stats_interval; 		/*log seconds*/
	int kernel_leap;
	int sanity_freq_limit;
	int time_source;
	struct clock_description clock_desc;
	enum filter_type delay_filter;
	int delay_filter_length;
	int boundary_clock_jbod;
};

struct dataset {
	UInteger8            priority1;			// 用于计算最佳 master 时钟，值越低优先级越高
	struct ClockIdentity identity;
	struct ClockQuality  quality;
	UInteger8            priority2;			// 用于计算最佳 master 时钟，值越低优先级越高
	UInteger16           stepsRemoved;		// 本地到grandmaster 通信的路径数
	struct PortIdentity  sender;
	struct PortIdentity  receiver;
};

struct currentDS {
	UInteger16   stepsRemoved;				// 本地到grandmaster 通信的路径数
	TimeInterval offsetFromMaster;			// 主从时钟之间的时间差（由从机计算）offsetFromMaster = 在从机的时间 - 在主机的时间
	TimeInterval meanPathDelay;				// 主从之间平均传输时间（由从机计算）
} PACKED;

struct parentDS {
	struct PortIdentity  parentPortIdentity;			// master的端口唯一标识
	UInteger8            parentStats;					// 为1时，表示 observedParentOffsetScaledLogVariance 和 observedParentClockPhaseChangeRate 生效
	UInteger8            reserved;
	UInteger16           observedParentOffsetScaledLogVariance;		// 获取到的父时钟的方差(没什么用)
	Integer32            observedParentClockPhaseChangeRate;		// 父时钟相位变化率的估计值（没什么用）
	UInteger8            grandmasterPriority1;			// grandmaster的优先级1
	struct ClockQuality  grandmasterClockQuality;		// grandmaster的时钟质量
	UInteger8            grandmasterPriority2;			// grandmaster的优先级2
	struct ClockIdentity grandmasterIdentity;			// grandmaster的唯一标识
} PACKED;

struct parent_ds {
	struct parentDS pds;
	struct ClockIdentity *ptl;
	unsigned int path_length;
};

#define CURRENT_UTC_OFFSET  35 /* 1 Jul 2012 */
#define INTERNAL_OSCILLATOR 0xA0

struct timePropertiesDS {
	Integer16    currentUtcOffset;			// 与UTC偏差，等于 TAI - UTC （单位秒）
	/**
	 * 
	 * #define LEAP_61        (1<<0)		// 表示UTC日最后一份中位61秒
	 * #define LEAP_59        (1<<1)		// 表示UTC日最后一分钟为59秒
	 * #define UTC_OFF_VALID  (1<<2) 		// 表示 currentUtcOffset 是否有效
	 * #define PTP_TIMESCALE  (1<<3)		// 表示 grandmaster是否为PTP
	 * #define TIME_TRACEABLE (1<<4)		// 表示 currentUtcOffset 可以追述到主要参考
	 * #define FREQ_TRACEABLE (1<<5)		// 表示时钟的频率来源可靠
	 */
	UInteger8    flags;						
	Enumeration8 timeSource;				// 用于描述grandmaster的时间源，数值越低 越精准，最低为原子震荡时钟				
} PACKED;

struct portDS {
	struct PortIdentity portIdentity;			// 表示本地的时钟端口唯一标识
	/**
	 * 端口状态
	 * INITIALIZING 	01 
	 * FAULTY 			02 
	 * DISABLED 		03 
	 * LISTENING 		04 
	 * PRE_MASTER 		05 
	 * MASTER 			06 
	 * PASSIVE 			07 
	 * UNCALIBRATED 	08 
	 * SLAVE 			09
	 */
	Enumeration8        portState;				
	Integer8            logMinDelayReqInterval;	// 发送 Delay_Req 的最小间隔
	TimeInterval        peerMeanPathDelay;		// P2P 网络里平均路径单向传输延迟的估值，如果 delayMechnism是END2END，那么这个值为0; 如果 delayMechanism 为 P2P, 该值有效
	Integer8            logAnnounceInterval;	// Announce 消息发送间隔（s）的对数
	UInteger8           announceReceiptTimeout;	// Announce 接收超时时间（s）
	Integer8            logSyncInterval;		// Sync 消息发送间隔（s）的对数

	/**
	 * E2E			01		该 port 用于 请求-响应机制
	 * P2P			02		该 port 用于 P2P 机制
	 * DISABLE		FE		自动配置（不在PTP标准下）
	 */
	Enumeration8        delayMechanism;			 
	Integer8            logMinPdelayReqInterval; 	// 发送 PDelayReq 的最小间隔
	UInteger8           versionNumber;				// 该协议的版本，一般为2
} PACKED;

#define FRI_ASAP (-128)

struct port_defaults {
	Integer64 asymmetry;
	Integer8 logAnnounceInterval;				
	Integer8 logSyncInterval;					// sync 消息发送间隔(s)的对数
	Integer8 logMinDelayReqInterval;			// 最小的Delay_Req 发送间隔（s）的对数
	Integer8 logMinPdelayReqInterval;			// 最小的PDelay_Req 发送间隔（s）的对数
	UInteger8 announceReceiptTimeout;
	UInteger8 syncReceiptTimeout;
	UInteger8 transportSpecific;
	int announce_span;
	int path_trace_enabled;
	int follow_up_info;
	int freq_est_interval; /*log seconds*/
	struct fault_interval flt_interval_pertype[FT_CNT];
	UInteger32 neighborPropDelayThresh; /*nanoseconds*/
	int min_neighbor_prop_delay; /*nanoseconds*/
	int tx_timestamp_offset; /*发送时获取时间所用的时间，文档中的 ingress 单位 nanoseconds*/
	int rx_timestamp_offset; /*接收时计算时间所用的时间，文档中的 egress 单位 nanoseconds*/
};

#endif
